package cn.jhz.learn.community_dynamic.app.controller;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonProperty;

import cn.jhz.learn.community_dynamic.CommunityDynamicApplication;
import cn.jhz.learn.community_dynamic.common.bean.JsonData;
import cn.jhz.learn.community_dynamic.common.exception.RequestException;
import cn.jhz.learn.community_dynamic.dao.CommentJpaRepository;
import cn.jhz.learn.community_dynamic.dao.PostJpaRepository;
import cn.jhz.learn.community_dynamic.manager.CommentManager;
import cn.jhz.learn.community_dynamic.model.CommentEntity;
import cn.jhz.learn.community_dynamic.model.PostEntity;
import cn.jhz.learn.community_dynamic.model.UserEntity;
import cn.jhz.learn.community_dynamic.security.helper.LoginHelper;
import cn.jhz.learn.community_dynamic.service.CommentService;
import lombok.Getter;

@RestController
@RequestMapping("api/")
public class CommentController {
    private final PostJpaRepository postJpaRepository;
    private final CommentJpaRepository commentJpaRepository;
    private final CommentManager commentManager;
    private final CommentService commentService;

    @Getter
    private class CommentView {
	private Integer id;
	private Integer fid;
	@JsonProperty("user_id")
	private Long userId;
	private String userpic;
	private String username;
	private Date create_time;
	private String data;

	private CommentView(CommentEntity entity) {
	    this.id = entity.getId();
	    this.fid = entity.getFatherComment() == null ? 0 : entity.getFatherComment().getId();
	    this.userId = entity.getUser().getLoginId();
	    this.userpic = entity.getUser().getUserpic();
	    this.username = entity.getUser().getUsername();
	    this.create_time = entity.getCreateTime();
	    this.data = entity.getData();
	}
    }

    @Autowired
    public CommentController(PostJpaRepository postJpaRepository, CommentJpaRepository commentJpaRepository,
	    CommentManager commentManager, CommentService commentService) {
	super();
	this.postJpaRepository = postJpaRepository;
	this.commentJpaRepository = commentJpaRepository;
	this.commentManager = commentManager;
	this.commentService = commentService;
    }

    /**
     * TODO 缺少参数合法性校验
     * 
     * @param postId
     * @param type
     * @return
     */
    @PostMapping(value = "auth/support", consumes = "application/x-www-form-urlencoded")
    @PreAuthorize("hasAuthority('support::create')")
    public JsonData support(@RequestParam("post_id") Integer postId, @RequestParam("type") Byte type) {
	/**
	 * 1.判断postId是否有效 2.是否公开(保密内容不能点赞) 3.是否属于当前访问者(作者不能给自己点赞) 4.是否已经点赞过了(不能重复点赞)
	 */
	Optional<PostEntity> post = this.postJpaRepository.findByIdAndStatus(postId, (byte) 1);
	if (post.orElseThrow(() -> new RequestException("文章不存在!")).getIsOpen().equals((byte) 1)) {
	    Optional<?> requester = LoginHelper.getLoginUser();
	    if (requester.isPresent()) {
		if (((UserEntity) requester.get()).getId().equals(post.get().getId())) {
		    throw new RequestException("无法为自己的文章点赞!");
		}
	    } else {
		// TODO 登录异常
		throw new RequestException("登录异常!");
	    }
	    (type.equals((byte) 0) ? post.get().getSupportUsers() : post.get().getUnSupportUsers())
		    .add((UserEntity) requester.get());
	    this.postJpaRepository.flush();
	} else {
	    throw new RequestException("权限不足!");
	}

	return JsonData.newSuccessInstance();
    }

    /**
     * 1.postId进行有效校验 2.fid若不等于0要判断是否有效 ,fid 是否属于当前postId 3.postId校验是否公开、及属于请求者
     * 4.data 进行合法性校验 5.是否公开(保密内容不能评论) 6.是否属于当前访问者(作者可以为自己评论)
     * 
     * TODO 缺少参数合法性校验
     * 
     * @param fid
     * @param data
     * @param postId
     * @return
     */
    @PostMapping(value = "auth/post/comment", consumes = "application/x-www-form-urlencoded")
    @PreAuthorize("hasAuthority('comment::create')")
    public JsonData comment(@RequestParam("fid") Integer fid, @RequestParam("data") String data,
	    @RequestParam("post_id") Integer postId) {
	Optional<CommentEntity> comment = Optional.empty();
	Optional<PostEntity> postOptional = Optional.empty();
	if (fid > 0) {
	    comment = this.commentJpaRepository.findByIdAndStatus(fid, (byte) 1);
	    if (comment.orElseThrow(() -> new RequestException("无效评论!")).getPost().getId().equals(postId)) {
		postOptional = Optional.of(comment.get().getPost());
	    } else {
		throw new RequestException("无效评论!");
	    }
	}

	List<Integer> cache = this.commentService.getReviewCache(CommunityDynamicApplication.REVIEW_CACHE).get();

	cache.add(this.commentService.review(this.commentManager.addInstance(CommentEntity.builder()
		.createTime(new Date()).data(data).fatherComment(comment.isPresent() ? comment.get() : null)
		.post(postOptional.orElse(this.postJpaRepository.findByIdAndStatus(postId, (byte) 1)
			.orElseThrow(() -> new RequestException("无效评论!"))))
		.user((UserEntity) LoginHelper.getLoginUser().orElseThrow(() -> new RequestException("登录异常!"))).fnum(0)
		.status((byte) 1).build())).getId());

	this.commentService.putReviewCache(CommunityDynamicApplication.REVIEW_CACHE, cache);

	return JsonData.newSuccessInstance();
    }

    @GetMapping("post/{post_id}/comment")
    public JsonData comment(@PathVariable("post_id") Integer postId) {
	Optional<PostEntity> postOptional = this.postJpaRepository.findByIdAndStatus(postId, (byte) 1);
	if (postOptional.isPresent()) {
	    return JsonData
		    .newSuccessInstance(this.commentJpaRepository.findByPostAndStatus(postOptional.get(), (byte) 1)
			    .parallelStream().map(CommentView::new).collect(Collectors.toList()));
	} else {
	    throw new RequestException("文章不存在!");
	}
    }

}
